home *** CD-ROM | disk | FTP | other *** search
/ Sun Solutions 1997 April to September / Sun Solutions CD - APR '97 - SEP '97 (704-3778-12 Rev. H)(Sun Microsystems, Inc.)(1997).iso / products / Hyperion / src / plat_svr4.c < prev    next >
C/C++ Source or Header  |  1997-02-26  |  7KB  |  398 lines

  1. /*
  2.  * @(#)plat_svr4.c    1.1    1/2/94
  3.  *
  4.  * SVR4 specific.  Much of this is similar to plat_hpux.c.
  5.  */
  6. static char *ident = "@(#)plat_svr4.c    1.1\t1/2/94";
  7.  
  8. #ifdef SVR4
  9.  
  10. #include <sys/types.h>
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #include <string.h>
  14. #include <fcntl.h>
  15. #include <stdlib.h>
  16. #include <unistd.h>
  17. #include <signal.h>
  18. #include <sys/mkdev.h>
  19. #include <sys/stat.h>
  20. #include <sys/sdi.h>
  21. #include <sys/sdi_edt.h>
  22. #include <sys/scsi.h>
  23. #include <errno.h>
  24.  
  25. #include "struct.h"
  26.  
  27. #define    DEFAULT_CD_DEVICE    "/dev/rcdrom/cd0"
  28.  
  29. void *malloc();
  30. char *strchr();
  31.  
  32. int    min_volume = 0;
  33. int    max_volume = 255;
  34.  
  35. extern char    *cd_device;
  36.  
  37. /*
  38.  * Initialize the drive.  A no-op for the generic driver.
  39.  */
  40. int
  41. gen_init(d)
  42.     struct wm_drive    *d;
  43. {
  44.     return (0);
  45. }
  46.  
  47. /*
  48.  * Get the number of tracks on the CD.
  49.  */
  50. int
  51. gen_get_trackcount(d, tracks)
  52.     struct wm_drive    *d;
  53.     int        *tracks;
  54. {
  55.     return (wm_scsi2_get_trackcount(d, tracks));
  56. }
  57.  
  58. /*
  59.  * Get the start time and mode (data or audio) of a track.
  60.  */
  61. int
  62. gen_get_trackinfo(d, track, data, startframe)
  63.     struct wm_drive    *d;
  64.     int        track, *data, *startframe;
  65. {
  66.     return (wm_scsi2_get_trackinfo(d, track, data, startframe));
  67. }
  68.  
  69. /*
  70.  * Get the number of frames on the CD.
  71.  */
  72. int
  73. gen_get_cdlen(d, frames)
  74.     struct wm_drive    *d;
  75.     int        *frames;
  76. {
  77.     int        tmp;
  78.  
  79.     return (wm_scsi2_get_cdlen(d, frames));
  80. }
  81.  
  82. /*
  83.  * Get the current status of the drive: the current play mode, the absolute
  84.  * position from start of disc (in frames), and the current track and index
  85.  * numbers if the CD is playing or paused.
  86.  */
  87. int
  88. gen_get_drive_status(d, oldmode, mode, pos, track, index)
  89.     struct wm_drive    *d;
  90.     enum cd_modes    oldmode, *mode;
  91.     int        *pos, *track, *index;
  92. {
  93.     return (wm_scsi2_get_drive_status(d, oldmode, mode, pos, track, index));
  94. }
  95.  
  96. /*
  97.  * Set the volume level for the left and right channels.  Their values
  98.  * range from 0 to 100.
  99.  */
  100. int
  101. gen_set_volume(d, left, right)
  102.     struct wm_drive    *d;
  103.     int        left, right;
  104. {
  105.     return (wm_scsi2_set_volume(d, left, right));
  106. }
  107.  
  108. /*
  109.  * Read the initial volume from the drive, if available.  Each channel
  110.  * ranges from 0 to 100, with -1 indicating data not available.
  111.  */
  112. int
  113. gen_get_volume(d, left, right)
  114.     struct wm_drive    *d;
  115.     int        *left, *right;
  116. {
  117.     return (wm_scsi2_get_volume(d, left, right));
  118. }
  119.  
  120. /*
  121.  * Pause the CD.
  122.  */
  123. int
  124. gen_pause(d)
  125.     struct wm_drive    *d;
  126. {
  127.     return (wm_scsi2_pause(d));
  128. }
  129.  
  130. /*
  131.  * Resume playing the CD (assuming it was paused.)
  132.  */
  133. int
  134. gen_resume(d)
  135.     struct wm_drive    *d;
  136. {
  137.     return (wm_scsi2_resume(d));
  138. }
  139.  
  140. /*
  141.  * Stop the CD.
  142.  */
  143. int
  144. gen_stop(d)
  145.     struct wm_drive    *d;
  146. {
  147.     return (wm_scsi2_stop(d));
  148. }
  149.  
  150. /*
  151.  * Play the CD from one position to another (both in frames.)
  152.  */
  153. int
  154. gen_play(d, start, end)
  155.     struct wm_drive    *d;
  156.     int        start, end;
  157. {
  158.     return (wm_scsi2_play(d, start, end));
  159. }
  160.  
  161. /*
  162.  * Eject the current CD, if there is one.
  163.  */
  164. int
  165. gen_eject(d)
  166.     struct wm_drive    *d;
  167. {
  168.     return (wm_scsi2_eject(d));
  169. }
  170.  
  171. static int
  172. create_cdrom_node(char *dev_name)
  173. {
  174.     char pass_through[100];
  175.     int file_des;
  176.     dev_t pass_thru_device;
  177.     int err;
  178.     int ccode;
  179.  
  180.  
  181.     strcpy(pass_through, dev_name);
  182.     strcat(pass_through, "p" );
  183.  
  184.     if (setreuid(-1,0) < 0)
  185.     {
  186.         perror("setregid/setreuid/access");
  187.         exit(1);
  188.     }
  189.  
  190.     ccode = access(pass_through, F_OK);
  191.     
  192.     if (ccode < 0)
  193.     {
  194.         if ((file_des = open(dev_name, O_RDONLY)) < 0)
  195.         {
  196.             perror("open cdrom devices failed");
  197.             return -1;
  198.         }
  199.  
  200.         if (ioctl(file_des, B_GETDEV, &pass_thru_device) < 0)
  201.         {
  202.             perror("Call to get pass-through device number failed");
  203.             return -1;
  204.         }
  205.  
  206.         (void)close(file_des);
  207.  
  208.         if (mknod(pass_through, (S_IFCHR | S_IREAD | S_IWRITE),
  209.             pass_thru_device) < 0)
  210.         {
  211.             perror("Unable to make pass-through node");
  212.             return -1;
  213.         }
  214.  
  215.             if (chown(pass_through, 0 , 0) < 0)
  216.         {
  217.             perror("chown");
  218.             return -1;
  219.         }
  220.  
  221.         if (chmod(pass_through, 0660 ) < 0)
  222.         {
  223.             perror("chmod");
  224.             return -1;
  225.         }
  226.     }
  227.     
  228.     file_des = open( pass_through, O_RDWR);
  229.     err = errno;
  230.  
  231.     if ( (setreuid(-1,getuid()) < 0) || (setregid(-1,getgid()) < 0) )
  232.     {
  233.         perror("setreuid/setregid");
  234.         exit(1);
  235.     }
  236.     errno = err;
  237.     return file_des;
  238. }
  239.  
  240. /*
  241.  * Open the CD and figure out which kind of drive is attached.
  242.  */
  243. int
  244. wmcd_open(d)
  245.     struct wm_drive    *d;
  246. {
  247.     int        fd, flag = 1;
  248.     static int    warned = 0;
  249.     char        vendor[9], model[17], rev[5];
  250.  
  251.     if (d->fd >= 0)        /* Device already open? */
  252.         return (0);
  253.     
  254.     if (cd_device == NULL)
  255.         cd_device = DEFAULT_CD_DEVICE;
  256.  
  257.     d->fd = create_cdrom_node(cd_device); /* this will do open */
  258.  
  259.     if (d->fd < 0)
  260.     {
  261.         if (errno == EACCES)
  262.         {
  263.             if (! warned)
  264.             {
  265.                 fprintf(stderr,"Cannot access %s\n",cd_device);
  266.                 warned++;
  267.             }
  268.         }
  269.         else if (errno != EINTR)
  270.         {
  271.             perror(cd_device);
  272.             exit(1);
  273.         }
  274.  
  275.         /* No CD in drive. (Is this true also for svr4 ? XXX ) */
  276.         return (1);
  277.     }
  278.  
  279.     if (warned)
  280.     {
  281.         warned = 0;
  282.         fprintf(stderr, "Thank you.\n");
  283.     }
  284.  
  285.     /* Now fill in the relevant parts of the wm_drive structure. */
  286.  
  287.     fd = d->fd;
  288.  
  289.     if (wm_scsi_get_drive_type(d, vendor, model, rev) < 0)
  290.     {
  291.         perror("Cannot inquiry drive for it's type");
  292.         exit(1);
  293.     }
  294.     *d = *(find_drive_struct(vendor, model, rev));
  295.     about_set_drivetype(d->vendor, d->model, rev);
  296.  
  297.     d->fd = fd;
  298.  
  299.     return (0);
  300. }
  301.  
  302. void
  303. keep_cd_open() { }
  304.  
  305. /*
  306.  * Send a SCSI command out the bus.
  307.  */
  308. int 
  309. wm_scsi(d, xcdb, cdblen, retbuf, retbuflen, getreply)
  310.     struct wm_drive *d;
  311.     unsigned char *xcdb;
  312.     int cdblen;
  313.     int getreply;
  314.     char *retbuf;
  315.     int retbuflen;
  316. {
  317.     int ccode;
  318.     int file_des = d->fd;
  319.     int i,j;
  320.     unsigned char sense_buffer[ SENSE_SZ ];
  321.     int errno_save;
  322.  
  323.     /* getreply == 1 is read, == 0 is write */
  324.     
  325.     struct sb sb;
  326.     struct scs scs;
  327.  
  328.         sb.sb_type = ISCB_TYPE;
  329.  
  330.     sb.SCB.sc_comp_code = SDI_PROGRES;
  331.     sb.SCB.sc_int = NULL;
  332.     sb.SCB.sc_wd = 0;
  333.     sb.SCB.sc_dev.sa_major = 0;
  334.     sb.SCB.sc_dev.sa_minor = 0;
  335.     sb.SCB.sc_dev.sa_lun = 0;
  336.     sb.SCB.sc_dev.sa_exlun = 0;
  337.     sb.SCB.sc_status = 0;
  338.     sb.SCB.sc_link = (struct sb *) NULL;
  339.     sb.SCB.sc_resid = 0;
  340.  
  341.     sb.SCB.sc_cmdpt = (void *)xcdb;
  342.     sb.SCB.sc_cmdsz = cdblen;
  343.  
  344.     sb.SCB.sc_datapt = retbuf ;
  345.     sb.SCB.sc_datasz = retbuflen ;
  346.  
  347.     if (getreply == 1)
  348.         sb.SCB.sc_mode = SCB_READ;
  349.     else
  350.         sb.SCB.sc_mode = SCB_WRITE;
  351.  
  352.     sb.SCB.sc_time = 500;
  353.  
  354.     ccode =  ioctl(file_des, SDI_SEND,  &sb);
  355.  
  356.     if ( (sb.SCB.sc_comp_code != 0xd000000e ) ||
  357.                 ( sb.SCB.sc_status != 02) )
  358.         return ccode;
  359.  
  360.     errno_save = errno;
  361.  
  362.         sb.SCB.sc_comp_code = SDI_PROGRES;
  363.         sb.SCB.sc_int = NULL;
  364.         sb.SCB.sc_wd = 0;
  365.         sb.SCB.sc_dev.sa_major = 0;
  366.         sb.SCB.sc_dev.sa_minor = 0;
  367.         sb.SCB.sc_dev.sa_lun = 0;
  368.         sb.SCB.sc_dev.sa_exlun = 0;
  369.         sb.SCB.sc_status = 0;
  370.         sb.SCB.sc_link = (struct sb *) NULL;
  371.         sb.SCB.sc_resid = 0;
  372.  
  373.     scs.ss_op    =    SS_REQSEN;
  374.     scs.ss_lun    =    0;
  375.     scs.ss_addr1    =    0;
  376.     scs.ss_addr    =    0;
  377.     scs.ss_len    =    SENSE_SZ;
  378.     scs.ss_cont    =    0;
  379.  
  380.     sb.SCB.sc_cmdpt = SCS_AD(&scs);
  381.     sb.SCB.sc_cmdsz = SCS_SZ;
  382.     sb.SCB.sc_datapt = sense_buffer;
  383.     sb.SCB.sc_datasz = 18;
  384.     sb.SCB.sc_mode = SCB_READ;
  385.     sb.SCB.sc_time = 5000;
  386.  
  387.     if (ioctl(file_des, SDI_SEND,  &sb) < 0)
  388.     {
  389.         fprintf(stderr,"Cannot read sense.\n");
  390.         exit(-1);
  391.     }
  392.  
  393.     errno=errno_save;
  394.     return -1;
  395. }
  396.  
  397. #endif
  398.